/*
 * #%L
 * Client
 * %%
 * Copyright (C) 2011 Ractoc.com
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.ractoc.opengamefinder.client.plugins.nifty;

import org.apache.log4j.Logger;

import com.ractoc.opengamefinder.api.messages.ErrorMessage;
import com.ractoc.opengamefinder.api.results.MessageResultsErrorCodes;
import com.ractoc.opengamefinder.client.ConfigLocator;
import com.ractoc.opengamefinder.client.plugins.messages.DisplayScreenMessage;
import com.ractoc.opengamefinder.client.plugins.results.DisplayScreenMessageResult;
import com.ractoc.pffj.api.BasePluginMessageResult;
import com.ractoc.pffj.api.PluginMessage;

import de.lessvoid.nifty.Nifty;

/**
 * Base screen class. All screens extend this class.
 * 
 * @author ractoc
 * @version 0.1
 */
public abstract class BaseScreen {

    /**
     * Nifty instance, all screens need this so it has been placed and is
     * instantiated, here.
     */
    protected static Nifty nifty;

    private static final String XML_EXT = ".xml";

    private static final String CONFIGURATION_NIFTY_ROOT = "configuration/nifty/";

    private static Logger logger = Logger.getLogger(BaseScreen.class.getName());

    /**
     * Process the message meant for this screen.
     * Currently supports the following messages:
     * <ul>
     * <li>ErrorMessage</li>
     * <li>DisplayScreenMessage</li>
     * <ul>
     * All other message are passed on to processDisplayScreenMessage.
     * 
     * @param msg The message to process.
     * @return The result of processing the message.
     */
    public final BasePluginMessageResult processMessage(final PluginMessage msg) {
        if (nifty == null) {
            initialize();
        }
        BasePluginMessageResult result = null;
        if (msg instanceof ErrorMessage) {
            result = processErrorMessage(msg);
        } else if (msg instanceof DisplayScreenMessage) {
            result = processDisplayScreenMessage(msg);
        } else {
            result = screenProcessing(msg);
        }
        return result;
    }

    private void initialize() {
        nifty = NiftyPlugin.getNifty();
    }

    private BasePluginMessageResult processDisplayScreenMessage(final PluginMessage msg) {
        BasePluginMessageResult result;
        final DisplayScreenMessage dsMsg = (DisplayScreenMessage) msg;
        String configFile = ConfigLocator.getCustomConfig(dsMsg.getScreenName() + XML_EXT);
        if (configFile == null) {
            configFile = CONFIGURATION_NIFTY_ROOT + dsMsg.getScreenName() + XML_EXT;
        }
        logger.info("displaying screen " + dsMsg.getScreenName() + " from configuration file "
                + configFile);
        nifty.fromXml(configFile, dsMsg.getScreenName());

        logger.debug("current active screen = " + nifty.getCurrentScreen().getScreenId());

        result = new DisplayScreenMessageResult();
        result.setErrorCode(MessageResultsErrorCodes.SUCCESS);
        return result;
    }

    private BasePluginMessageResult processErrorMessage(final PluginMessage msg) {
        BasePluginMessageResult result;
        final ErrorMessage eMsg = (ErrorMessage) msg;
        //TODO: figure out a way to have a default localization in the jar and a custom one outside the jar.
        MessageBox.showMessageBox(nifty, "${ogf-error." + eMsg.getErrorCode().name() + "}", "/images/error.jpg");
        result = new DisplayScreenMessageResult();
        result.setErrorCode(MessageResultsErrorCodes.SUCCESS);
        return result;
    }

    /**
     * This method needs to be extended and is called from processMessage to
     * process screen specific mesages.
     * 
     * @param msg The message to be processed.
     * @return The result from processing the message.
     */
    protected abstract BasePluginMessageResult screenProcessing(PluginMessage msg);

}
